﻿using System;
using System.Drawing;
using System.Windows.Forms;
using FireStarter.Base;
using FireStarter.Base.BusinessObjectMerger;
using Firestarter.DB.Schema.BO;
using Firestarter.DB.Schema.Logic;
using Habanero.Base.Exceptions;
using Habanero.Faces.Base;
using Habanero.Faces.Win;


namespace Firestarter.DB.Schema.UI
{

    public class MergeBOsControl : UserControlWin, IFormControl
    {

        private IPanel _contentPanel;
        private IPanel _buttonPanel;
        private IMergableBo _boSelectedInTree;
        private const string TEXT_MERGE_WITH = "Merge with :";
        private const string TEXT_MERGE_INTO = "Merge into :";
        public IMergableBo BoSelectedInTree
        {
            get { return _boSelectedInTree; }
            set 
            {
                _boSelectedInTree = value;
                if (_boSelectedInTree.PendingChangeType==ChangeType.Add)
                {
                    MergeBOsLabel.Text = TEXT_MERGE_WITH;
                }
                else if (_boSelectedInTree.PendingChangeType==ChangeType.Delete)
                {
                    MergeBOsLabel.Text = TEXT_MERGE_INTO;
                }
            }
        }

        public string BoDisplayText { get; set; }
        public ILabel MergeBOsLabel { get; private set; }
        public IButton ButtonOk { get; private set; }
        public IButton ButtonCancel { get; private set; }

        public MergeBOsControl()
        {
            SetupContentPanel(GlobalUIRegistry.ControlFactory);
            SetupButtonPanel(GlobalUIRegistry.ControlFactory);

            var borderLayoutManager = GlobalUIRegistry.ControlFactory.CreateBorderLayoutManager(this);
            borderLayoutManager.AddControl(_contentPanel, BorderLayoutManager.Position.North);
            borderLayoutManager.AddControl(_buttonPanel, BorderLayoutManager.Position.Centre);
            
        }

        public IBOComboBoxSelector MergeableBoCombo { get; private set; }


        private static void MergeBOs(IMergableBo toBO, IMergableBo fromBO)
        {
            SchemaMerger.SetupMergeableBORegistry();
            var mergeBO = MergeableBORegistry.Instance.Resolve(toBO.GetType());
            toBO = mergeBO.MergeBOFrom(fromBO, toBO);
            toBO.PendingChangeType = ChangeType.Rename;
            fromBO.MarkForDelete();
        }

        private void SetupContentPanel(IControlFactory factory)
        {
            _contentPanel = factory.CreatePanel(factory);
            _contentPanel.ClientSize = new Size(Width, 50);
            var flowLayoutManager = new FlowLayoutManager(_contentPanel, factory);
            MergeBOsLabel = CreateRenamedBoLabel(factory);
            MergeableBoCombo = factory.CreateComboBoxSelector();

            MergeableBoCombo.DropDownWidth = 300;
            flowLayoutManager.AddControl(MergeBOsLabel);
            flowLayoutManager.AddControl(MergeableBoCombo);
            flowLayoutManager.GapSize = 10;
        }

        private void SetupButtonPanel(IControlFactory factory)
        {
            _buttonPanel = factory.CreatePanel(factory);
            _buttonPanel.ClientSize = new Size(Width, 40);
            var flowLayoutManager = new FlowLayoutManager(_buttonPanel, factory)
                                                  {
                                                      Alignment = FlowLayoutManager.Alignments.Right,
                                                      GapSize = 5,
                                                      BorderSize = 10
                                                  };

            ButtonOk = CreateOkButton(factory);
            ButtonOk.Click += delegate
            {
                IMergableBo mergeToBo;
                IMergableBo mergeFromBo;
                try
                {
                    mergeToBo = GetToBeDeletedMergableBo();
                    mergeFromBo = GetToBeAddedMergableBo();

                }
                    //TODO andrew 08 Oct 2010: Changed this to Habanero Exception
                catch (InvalidOperationException)
                {
                    MessageBox.Show(@"Please ensure that an item is selected from the dropdown list.");
                    return;                   
                }

                if (MessageBox.Show(@"Are you sure you want to merge these items?",
                                    @"Merge",
                                    System.Windows.Forms.MessageBoxButtons.YesNo,
                                    System.Windows.Forms.MessageBoxIcon.Warning) !=
                                    System.Windows.Forms.DialogResult.Yes) return;

                MergeBOs(mergeToBo, mergeFromBo);
                if (ParentForm != null) ParentForm.Close();
            };
            ButtonCancel = CreateCancelButton(factory);
            ButtonCancel.Click += delegate { if (ParentForm != null) ParentForm.Close(); };
            flowLayoutManager.AddControl(ButtonCancel);
            flowLayoutManager.AddControl(ButtonOk);
        }


        private static ILabel CreateRenamedBoLabel(IControlFactory factory)
        {
            return CreateFormLabel(TEXT_MERGE_WITH, new Size(100, 25), factory);
        }

        private static ILabel CreateFormLabel(string text, Size labelSize, IControlFactory factory)
        {
            ILabel label = factory.CreateLabel(text);
            label.Size = labelSize;
            return label;
        }

        private static IButton CreateOkButton(IControlFactory factory)
        {
            return CreateFormButton("Ok", GetButtonSize(), 1, factory);
        }

        private static IButton CreateCancelButton(IControlFactory factory)
        {
            return CreateFormButton("Cancel", GetButtonSize(), 1, factory);
        }

        private static IButton CreateFormButton(String text, Size buttonSize, int tabIndex, IControlFactory factory)
        {
            IButton button = factory.CreateButton(text);
            button.Size = buttonSize;
            button.TabIndex = tabIndex;
            return button;
        }


        private static Size GetButtonSize()
        {
            const int buttonWidth = 60;
            const int buttonHeight = 25;
            return new Size(buttonWidth, buttonHeight);
        }

        public void SetForm(IFormHabanero form)
        {
        }

        /// <summary>
        /// Returns the mergable BO that the mergeFrom BO will merge to.
        /// </summary>
        /// <returns></returns>
        public IMergableBo GetToBeDeletedMergableBo()
        {
            return GetBOWithChangeType(ChangeType.Delete);
        }

        /// <summary>
        /// Returns the BO that will be merged into the mergeTo BO.
        /// </summary>
        /// <returns></returns>
        public IMergableBo GetToBeAddedMergableBo()
        {
            return GetBOWithChangeType(ChangeType.Add);
        }

        private IMergableBo GetBOWithChangeType(ChangeType changeType)
        {
            if (BoSelectedInTree.PendingChangeType == changeType) return BoSelectedInTree;
            if (BoSelectedInComboBox.PendingChangeType == changeType) return BoSelectedInComboBox;
            throw new HabaneroDeveloperException("PendingChangeType for BO should be Add or Delete");           
        }

        public IMergableBo BoSelectedInComboBox
        {
            get
            {
                IMergableBo mergeToBo = MergeableBoCombo.SelectedBusinessObject as IMergableBo;
                if (mergeToBo == null) throw new HabaneroDeveloperException("No item was selected from the Dropdown list.");
                return mergeToBo;
            }
        }
    }
}
